<template>
<div class="parent">
    <div id="container">
    </div>
    <div id="controls">
    </div>
</div>
</template>
<script setup lang="ts">
import { onMounted } from 'vue';
import * as THREE from 'three';
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js';

onMounted(()=>{
    const scene = new THREE.Scene();

    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.getElementById('container')?.appendChild(renderer.domElement);
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 5);
    camera.position.z = 2;

    class FogGUIHelper {
        private fog: any;
        private backgroundColor: any;
        constructor( fog:any, backgroundColor:any ) {
            this.fog = fog;
            this.backgroundColor = backgroundColor;
        }
        get near() {
            return this.fog.near;
        }
        set near( v ) {
            this.fog.near = v;
            this.fog.far = Math.max( this.fog.far, v );
        }

        get far() {
            return this.fog.far;
        }
        set far( v ) {
            this.fog.far = v;
            this.fog.near = Math.min( this.fog.near, v );
        }
        get color() {
            return `#${this.fog.color.getHexString()}`;
        }
        set color( hexString ) {
            this.fog.color.set( hexString );
            this.backgroundColor.set( hexString );
        }
    }

	{  //添加雾
		const near = 1;
		const far = 2;
		const color = 'lightblue';
		scene.fog = new THREE.Fog( color, near, far );
		scene.background = new THREE.Color( color );

        // const color = 0xFFFFFF;
        // const density = 0.1;
        // scene.fog = new THREE.FogExp2(color, density);

        const gui = new GUI({container: document.getElementById('controls')!!});
        const fogGUIHelper = new FogGUIHelper( scene.fog, scene.background );
		gui.add( fogGUIHelper, 'near', near, far ).listen();
		gui.add( fogGUIHelper, 'far', near, far ).listen();
		gui.addColor( fogGUIHelper, 'color' );
	}

    {
        const color = 0xFFFFFF;
        const intensity = 3;
        const light = new THREE.DirectionalLight( color, intensity );
        light.position.set( - 1, 2, 4 );
        scene.add( light );
    }

    const boxWidth = 1;
	const boxHeight = 1;
	const boxDepth = 1;
	const geometry = new THREE.BoxGeometry( boxWidth, boxHeight, boxDepth );

    function makeInstance( geometry:THREE.BufferGeometry, color:number, x:number ) {
        const material = new THREE.MeshPhongMaterial( { color } );
        // material.fog = false; //可以设置材质不受雾的影响
        const cube = new THREE.Mesh( geometry, material );
        scene.add( cube );
        cube.position.x = x;
        return cube;
    }
   
	const cubes = [
		makeInstance( geometry, 0x44aa88, 0 ),
		makeInstance( geometry, 0x8844aa, - 2 ),
		makeInstance( geometry, 0xaa8844, 2 ),
	];

    function resizeRendererToDisplaySize( renderer:THREE.WebGLRenderer ) {
        const canvas = renderer.domElement;
        const width = canvas.clientWidth;
        const height = canvas.clientHeight;
        const needResize = canvas.width !== width || canvas.height !== height;
        if ( needResize ) {
            renderer.setSize( width, height, false );
        }
        return needResize;
    }

    function render( time:number ) {
        time *= 0.001;
        if ( resizeRendererToDisplaySize( renderer ) ) {
            const canvas = renderer.domElement;
            camera.aspect = canvas.clientWidth / canvas.clientHeight;
            camera.updateProjectionMatrix();
        }

        cubes.forEach( ( cube, ndx ) => {
            const speed = 1 + ndx * .1;
            const rot = time * speed;
            cube.rotation.x = rot;
            cube.rotation.y = rot;
        } );
        renderer.render( scene, camera );
        requestAnimationFrame( render );
    }
    requestAnimationFrame( render );

});
</script>

<style scoped>
.parent { 
    position: relative;
    width: 100%;
    height: 100%;
}
.parent > * {
    position: absolute;
}
#controls {
    right: 0;
}
</style>